package com.vincent.service;

import com.vincent.common.enums.ResultMapKey;
import com.vincent.common.utils.AssertUtil;
import com.vincent.dao.ArticleCategoryDao;
import com.vincent.dao.ArticleDao;
import com.vincent.dao.ArticleVisitLogDao;
import com.vincent.model.Article;
import com.vincent.model.ArticleCategory;
import com.vincent.model.ArticleVisitLog;
import com.vincent.model.ArticleWithBLOBs;
import com.vincent.vo.SaveArticleVo;
import com.vincent.vo.UpdateArticleVo;
import org.apache.log4j.Logger;
import org.htmlparser.Parser;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.TextExtractingVisitor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by Vincent on 2014/12/20.
 */
@Service("articleService")
public class ArticleService {
    @Resource
    private ArticleCategoryDao articleCategoryDao;
    @Resource
    private ArticleDao articleDao;
    @Resource
    private ArticleVisitLogDao articleVisitLogDao;

    private static final Logger log = Logger.getLogger(ArticleService.class);

    private int text_length = 110;

    /**
     * 文章列表
     *
     * @param categoryid
     * @param pageNow
     * @param pageSize
     * @return
     */
    public Map<String, Object> findListPagination(int categoryid, int pageNow, int pageSize) {

        Map<String, Object> resultMap = new HashMap<String, Object>();
        //获取所有文章分类
        List<ArticleCategory> categoryList = articleCategoryDao.selectAll();
        //获取当前文章分类
        ArticleCategory articleCategory = getArticleCategoryByIdFromCache(categoryid, categoryList);
        AssertUtil.notNull(articleCategory, "文章分类不存在");
        //分页查询文章
        List<Article> articleList = new ArrayList<Article>();
        List<Integer> articleIdList = articleDao.selectPaginationIdList((pageNow - 1) * pageSize, pageSize, categoryid, true);
        for (Integer id : articleIdList) {
            ArticleWithBLOBs article = articleDao.getArticleById(id);
            String content = article.getContentText();
            if (content.length() > text_length) {
                content = content.substring(0, text_length) + "...";
            }
            article.setContentText(content);
            articleList.add(article);
        }
        //获取数目
        int pagenationNum = articleDao.getArticlePagenationNum(categoryid, true);
        Map<String, Object> paginationMap = new HashMap<String, Object>();
        paginationMap.put("data", articleList);
        paginationMap.put("dataNum", pagenationNum);
        paginationMap.put("pageNow", pageNow);
        paginationMap.put("pageSize", pageSize);
        paginationMap.put("pageNum", ((pagenationNum - 1) / pageSize) + 1);
        //获取最热的文章
        List<Integer> topArticleIdList = articleDao.getHotestArticles(10, categoryid, true);
        List<Article> topArticles = new ArrayList<Article>();
        for (Integer id : topArticleIdList) {
            ArticleWithBLOBs article = articleDao.getArticleById(id);
            topArticles.add(article);
        }

        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("categories", categoryList);
        dataMap.put("cagetory", articleCategory);
        dataMap.put("paginationMap", paginationMap);
        dataMap.put("hotArticles", topArticles);

        resultMap.put(ResultMapKey.SUCCESS.getCode(), dataMap);
        return resultMap;
    }

    /**
     * 文章内容页面
     *
     * @param id
     * @return
     */
    public Map<String, Object> articleContent(int id, String ip) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //获取所有文章分类
        List<ArticleCategory> categoryList = articleCategoryDao.selectAll();
        //获取指定文章
        Article article = articleDao.getArticleById(id);
        AssertUtil.notNull(article, "文章不存在");
        //保存文章访问日志
        ArticleVisitLog articleVisitLog = new ArticleVisitLog();
        articleVisitLog.setArticleId(id);
        articleVisitLog.setVisitTime(new Date());
        articleVisitLog.setVisitIp(ip);
        articleVisitLogDao.save(articleVisitLog);
        //获取文章类别
        ArticleCategory articleCategory = getArticleCategoryByIdFromCache(article.getCategoryId(), categoryList);
        //获取最热的文章
        List<Integer> topArticleIdList = articleDao.getHotestArticles(10, article.getCategoryId(), true);
        List<Article> topArticles = new ArrayList<Article>();
        for (Integer articleId : topArticleIdList) {
            ArticleWithBLOBs articleTemp = articleDao.getArticleById(articleId);
            topArticles.add(articleTemp);
        }
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("categories", categoryList);
        dataMap.put("cagetory", articleCategory);
        dataMap.put("hotArticles", topArticles);
        dataMap.put("article", article);

        resultMap.put(ResultMapKey.SUCCESS.getCode(), dataMap);
        return resultMap;
    }

    /**
     * 管理员后天 文章管理
     *
     * @return
     */
    public Map<String, Object> findArticleManage(int pageNow, int pageSize) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //获取所有文章分类
        List<ArticleCategory> categoryList = articleCategoryDao.selectAll();
        List<Integer> articleIdList = articleDao.selectPaginationIdList((pageNow - 1) * pageSize, pageSize, null, null);
        List<Article> articleList = new ArrayList<Article>();
        for (Integer id : articleIdList) {
            ArticleWithBLOBs articleWithBLOBs = articleDao.getArticleById(id);
            String title = articleWithBLOBs.getTitle();
            if (title.length() > 20) {
                articleWithBLOBs.setTitle(title.substring(0, 20) + "...");
            }
            ArticleCategory articleCategory = getArticleCategoryByIdFromCache(articleWithBLOBs.getCategoryId(), categoryList);
            articleWithBLOBs.setArticleCategory(articleCategory);
            articleList.add(articleWithBLOBs);
        }

        int num = articleDao.getArticlePagenationNum(null, null);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("data", articleList);
        dataMap.put("pageNow", pageNow);
        dataMap.put("pageSize", pageSize);
        dataMap.put("dataNum", num);
        dataMap.put("pageNum", ((num - 1) / pageSize) + 1);

        resultMap.put(ResultMapKey.SUCCESS.getCode(), dataMap);
        return resultMap;
    }
    public Map<String, Object> getArticleManage(int pageNow, int pageSize,String sort,String order) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //获取所有文章分类
        List<ArticleCategory> categoryList = articleCategoryDao.selectAll();
        List<Integer> articleIdList = articleDao.selectPaginationIdList((pageNow - 1) * pageSize, pageSize, null, null);
        List<Article> articleList = new ArrayList<Article>();
        for (Integer id : articleIdList) {
            ArticleWithBLOBs articleWithBLOBs = articleDao.getArticleById(id);
            String title = articleWithBLOBs.getTitle();
            if (title.length() > 20) {
                articleWithBLOBs.setTitle(title.substring(0, 20) + "...");
            }
            ArticleCategory articleCategory = getArticleCategoryByIdFromCache(articleWithBLOBs.getCategoryId(), categoryList);
            articleWithBLOBs.setArticleCategory(articleCategory);
            articleList.add(articleWithBLOBs);
        }

        int num = articleDao.getArticlePagenationNum(null, null);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("rows", articleList);
        dataMap.put("total", num);
        resultMap.put(ResultMapKey.SUCCESS.getCode(), dataMap);
        return resultMap;
    }

    /**
     * 获取所有文章分类
     *
     * @return
     */
    public Map<String, Object> getAllArticleCategories() {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //获取所有文章分类
        List<ArticleCategory> categoryList = articleCategoryDao.selectAll();
        resultMap.put(ResultMapKey.SUCCESS.getCode(), categoryList);
        return resultMap;
    }

    /**
     * 获取文章以及所有文章分类
     *
     * @param id
     * @return
     */
    public Map<String, Object> getAllArticleCategoriesAndArticle(int id) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //获取文章
        Article article = articleDao.getArticleById(id);
        //获取所有文章分类
        List<ArticleCategory> categoryList = articleCategoryDao.selectAll();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("article", article);
        dataMap.put("categories", categoryList);
        resultMap.put(ResultMapKey.SUCCESS.getCode(), dataMap);
        return resultMap;
    }

    /**
     * 删除文章
     *
     * @param ids
     * @return
     */
    public Map<String, Object> deleteArticles(Integer[] ids) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        articleVisitLogDao.deleteByArticleId(ids);
        articleDao.deleteArticles(ids);
        for(Integer id:ids){
            articleDao.clearCacheById(id);
        }
        resultMap.put(ResultMapKey.SUCCESS.getCode(), "删除文章成功");
        return resultMap;

    }

    /**
     * 保存文章
     *
     * @param vo
     * @param userId
     * @return
     */
    public Map<String, Object> saveArticle(SaveArticleVo vo, int userId) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
           ArticleWithBLOBs article = new ArticleWithBLOBs();
        Date date = new Date();
        article.setCreateDate(date);
        article.setAdminid(userId);
        article.setCategoryId(vo.getCategoryId());
        article.setTitle(vo.getTitle());
        article.setIsTop("on".equals(vo.getIsTop()));
        article.setIsPublication("on".equals(vo.getIsPublish()));
        article.setContent(vo.getContent());
        try {
            Parser parser = new Parser(article.getContent());
            TextExtractingVisitor visitor = new TextExtractingVisitor();
            parser.visitAllNodesWith(visitor);
            String text = visitor.getExtractedText();
            article.setContentText(text);
        } catch (ParserException e) {
            throw new RuntimeException(e);
        }
        articleDao.saveArticle(article);
        resultMap.put(ResultMapKey.SUCCESS.getCode(), "保存文章成功");
        return resultMap;
    }

    /**
     * 编辑文章
     *
     * @param vo
     * @param userId
     * @return
     */
    public Map<String, Object> updateArticle(UpdateArticleVo vo, int userId) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        ArticleWithBLOBs article =new ArticleWithBLOBs();
        article.setAdminid(userId);
        article.setCategoryId(vo.getCategoryId());
        article.setTitle(vo.getTitle());
        article.setIsTop("on".equals(vo.getIsTop()));
        article.setIsPublication("on".equals(vo.getIsPublish()));
        article.setContent(vo.getContent());
        article.setId(vo.getId());
        try {
            Parser parser = new Parser(article.getContent());
            TextExtractingVisitor visitor = new TextExtractingVisitor();
            parser.visitAllNodesWith(visitor);
            String text = visitor.getExtractedText();
            article.setContentText(text);
        } catch (ParserException e) {
            throw new RuntimeException(e);
        }
        articleDao.updateArticle(article);
        articleDao.clearCacheById(article.getId());
        resultMap.put(ResultMapKey.SUCCESS.getCode(), "编辑文章成功");
        return resultMap;
    }


    /**
     * 获取文章分类
     *
     * @param id
     * @param categoryList
     * @return
     */
    public ArticleCategory getArticleCategoryByIdFromCache(int id, List<ArticleCategory> categoryList) {
        for (ArticleCategory category : categoryList) {
            if (id == category.getId()) {
                return category;
            }
        }
        return null;
    }

}
